#region license
/*
 * Copyright (C) 2007 CchenSoft.com
 * 
 * This library is free software; you can redistribute it and/or modify it 
 * under the terms of the GNU Lesser General Public License 2.1 or later, as
 * published by the Free Software Foundation. See the included License.txt
 * or http://www.gnu.org/copyleft/lesser.html for details.
 * 
 * Author: Billy Zhang
 */
#endregion

using System;
using System.Collections.Generic;
using System.Text;
using System.Web.UI;
using System.Net;
using System.IO;
using System.Web.UI.WebControls;
using CchenSoft.Portal.Model;
using CchenSoft.Portal.Registry;
using CchenSoft.Portal.Util;
using System.Web;
using System.Web.UI.HtmlControls;
using CchenSoft.Portal.Service;
using CchenSoft.Portal.Spi.Registry;
using CchenSoft.Portal.Service.Impl;
using CchenSoft.Portal.Spi.Service;

namespace CchenSoft.Portal.Web
{
    [ParseChildren(true)]
    public class PortletControl : ThemeControl
    {
        private PortletInstance instance;
        private string hostName;
        private string portletContent;
        private PortletEntry entry;

        public PortletControl(string hostName, PortletInstance instance)
        {
            this.hostName = hostName;
            this.instance = instance;
            SkinFileName = "portlet_view.ascx";
            entry = PortalRegistry.Instance.GetPortlet(instance.PortletId);
            portletContent = ProcessPortletRequest();
        }
        //protected override 
        protected override void InitializeSkin(Control control)
        {
            //control.ID = instance.InstanceId;
            Label title = (Label)control.FindControl("title");
            title.Text = instance.Title;

            Label content = (Label)control.FindControl("content");
            content.Text = portletContent;

            HtmlContainerControl box = (HtmlContainerControl)control.FindControl("portlet_box");
            if (box != null)
            {
                box.ID = "_" + instance.InstanceId;
            }

            HtmlContainerControl box_h = (HtmlContainerControl)control.FindControl("portlet_box_h");
            if (box_h != null)
            {
                box_h.ID = "_" + instance.InstanceId + "_h";
            }

            HtmlContainerControl box_c = (HtmlContainerControl)control.FindControl("portlet_box_c");
            if (box_c != null)
            {
                box_c.ID = "_" + instance.InstanceId + "_c";
            }

            PortalURL portalUrl = PortalContext.Current.PortalURL;

            HyperLink hlnkCfg = (HyperLink)control.FindControl("hlnkCfg");
            HyperLink hlnkMax = (HyperLink)control.FindControl("hlnkMax");
            HyperLink hlnkNormal = (HyperLink)control.FindControl("hlnkNormal");
            HyperLink hlnkClose = (HyperLink)control.FindControl("hlnkClose");

            hlnkCfg.Visible = false;
            hlnkMax.Visible = false;
            hlnkNormal.Visible = false;
            hlnkClose.Visible = false;

            if (PortalContext.Current.IsAdmin)
            {
                if (!string.IsNullOrEmpty(entry.ConfigPath))
                {
                    PortalURL portalUrl2 = portalUrl.Clone();
                    portalUrl2.AppendParam("_" + instance.InstanceId + "_action", entry.ConfigPath);
                    hlnkCfg.NavigateUrl = portalUrl2.ToURLString();
                    hlnkCfg.Visible = true;
                }
                if (portalUrl.WindowState == WindowState.Normal)
                {
                    PortalURL portalUrl2 = portalUrl.Clone();
                    portalUrl2.WindowState = WindowState.Maximized;
                    portalUrl2.SetMaxInstance(instance.InstanceId);
                    hlnkMax.NavigateUrl = portalUrl2.ToURLString();
                    hlnkMax.Visible = true;
                    hlnkNormal.Visible = false;
                }
                else
                {
                    PortalURL portalUrl2 = portalUrl.Clone();
                    portalUrl2.WindowState = WindowState.Normal;
                    hlnkNormal.NavigateUrl = portalUrl2.ToURLString();
                    hlnkNormal.Visible = true;
                    hlnkMax.Visible = false;
                }

                hlnkClose.NavigateUrl = string.Format("javascript:Portal.closePortlet(\"{0}\");", box.ClientID);
            }
        }

        private string GetRequestAction()
        {
            PortalURL portalURL = PortalContext.Current.PortalURL;
            string action = portalURL.GetInstanceAction(instance.InstanceId);
            string queryString = portalURL.GetInstanceParams(instance.InstanceId);
            if (string.IsNullOrEmpty(action))
                action = entry.ViewPath;
            if (!string.IsNullOrEmpty(queryString))
                action += "?" + queryString;
            if (!action.StartsWith("/"))
                action = entry.RootPath + action;
            return action;
        }

        private Cookie TransformCookie(HttpCookie cookie)
        {
            Cookie result = new Cookie();
            result.Name = cookie.Name;
            result.Value = cookie.Values.ToString();
            result.Domain = HttpContext.Current.Request.Url.Host; // cookie.Domain;
            result.Expires = cookie.Expires;
            result.HttpOnly = cookie.HttpOnly;
            return result;
        }

        private string ProcessPortletRequest()
        {
            try
            {
                string action = GetRequestAction();

                Logger.Info("process portlet request: " + hostName + action, this.GetType());
                HttpWebRequest req = (HttpWebRequest)WebRequest.Create(hostName + action);

                // set browsers environment.
                HttpRequest request = HttpContext.Current.Request;
                req.UserAgent = request.UserAgent;

                // add headers.
                req.Headers.Add("portlet-instanceId", instance.InstanceId.ToString());
                req.Headers.Add("portal-exportservice", typeof(ExportServiceImpl).FullName);
                req.Headers.Add("portal-url", PortalContext.Current.PortalURL.ToXml());
                req.Headers.Add("producers", "21,PostList");
                req.Headers.Add("portlet-dataInput", instance.DataInput);

                if (req.CookieContainer == null)
                    req.CookieContainer = new CookieContainer();

                HttpCookieCollection coll = HttpContext.Current.Request.Cookies;
                for (int i = 0; i < coll.Count; i++)
                {
                    Cookie cookie = TransformCookie(coll[i]);
                    req.CookieContainer.Add(cookie);
                }

                HttpWebResponse resp = (HttpWebResponse)req.GetResponse();

                instance.DataOutput = resp.Headers["portlet-dataOutput"];

                StringBuilder ret = new StringBuilder();
                int BufferLengh = 8 * 1024;  // 16K

                using (StreamReader sr = new StreamReader(resp.GetResponseStream(), Encoding.UTF8))
                {
                    char[] buf = new char[BufferLengh];
                    int len = sr.Read(buf, 0, BufferLengh);
                    while (len > 0)
                    {
                        ret.Append(new string(buf, 0, len));
                        len = sr.Read(buf, 0, BufferLengh);
                    }
                }

                return ret.ToString();
            }
            catch (Exception ex)
            {
                Logger.Error(ex.Message + Environment.NewLine + ex.StackTrace, this.GetType());
                return "process portlet request fail!";
            }
        }
    }
}
